package com.appcenter.message.service;

import com.appcenter.jz.Logger.BusinessLogger;
import com.appcenter.jz.Logger.LoggerGenre;
import com.appcenter.jz.applications.GetItemsInput;
import com.appcenter.jz.applications.GetItemsOutput;
import com.appcenter.jz.config.ErrorJsonResult;
import com.appcenter.jz.config.JsonResult;
import com.appcenter.jz.expandmodel.ExpandDic;
import com.appcenter.jz.page.PagedResult;
import com.appcenter.jz.page.PagedResultRequest;
import com.appcenter.jz.unit.ObjectUnit;
import com.appcenter.message.config.RemoteProperties;
import com.appcenter.message.dto.Apps;
import com.appcenter.message.dto.DicDto;
import com.appcenter.message.expand.DingResponseJson;
import com.appcenter.message.expand.DingToken;
import com.appcenter.message.input.*;
import com.appcenter.message.input.externalapi.ReadMsgInput;
import com.appcenter.message.input.externalapi.SendMsgInput;
import com.appcenter.message.mapper.MessageTargetsMapper;
import com.appcenter.message.mapper.MessagesMapper;
import com.appcenter.message.model.MessageTargets;
import com.appcenter.message.model.Messages;
import com.appcenter.message.output.*;
import com.appcenter.message.output.externalapi.ReadMsgOutput;
import com.appcenter.message.output.externalapi.SendMsgOutput;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

import static org.apache.http.util.TextUtils.isBlank;


@EnableConfigurationProperties(RemoteProperties.class)
@Service
public class MessagesService {
    @Autowired
    MessagesMapper msgMapper;
    @Autowired
    MessageTargetsMapper msgTargetMapper;

    @Autowired
    private HttpAPIService httpAPIService;

    @Autowired
    com.appcenter.message.expand.DingDingMsg dingDingMsg;

    @Autowired
    RemoteProperties remoteProperties;

    @Autowired
    ObjectMapper objectMapper;

    /**
     *  创建人:Coke
     *  备注: 发送消息服务
     *  时间: 2019/4/26 14:49 
     *  参数: 
     */
    public SendMsgOutput SendMessage(SendMsgInput input) throws Exception {
        if (input.getMsg().getTitle() == null || input.getMsg().getTitle().equals("")) {
            throw new ErrorJsonResult("1000010", "消息标题不能为空");
        }
        if (input.getMsg().getSendMessageTargets() == null || input.getMsg().getSendMessageTargets().size() == 0) {
            throw new ErrorJsonResult("1000011", "消息接收人不能为空");
        }
        if (input.getMsg().getMessageTypes() == null || input.getMsg().getMessageTypes().size()==0) {
            throw new ErrorJsonResult("1000012", "消息类型不能为空");
        }
        SendMsgOutput output = new SendMsgOutput();
        String toNames = "";
        String toUserCode = "";
        for (SendMessageTargetInput item : input.getMsg().getSendMessageTargets()) {
            toNames += item.getTargetUserName() + ',';
            toUserCode += item.getTargetUserCode() + ',';
        }
        String SendResult = "";
        toNames = toNames.substring(0, toNames.length() - 1);
        //toUserCode = toUserCode.substring(0, toUserCode.length() - 1);

        List<Messages> msgModels = new ArrayList<Messages>();

        if(input.getMsg().getMessageTypes().size()>0){
            for (int i = 0; i < input.getMsg().getMessageTypes().size(); i++) {
                Messages msgModel = new Messages();
                if (input.getMsg().getMessageTypes()!=null &&input.getMsg().getMessageTypes().get(i).getMsgType().equals("站内信")) {
                    msgModel.setSendResultState("成功");
                } else if (input.getMsg().getMessageTypes().get(i).getMsgType().equals("电子邮件")) {
                    //_IUserSmtpEmailSender.Send(toUserCode, input.Title, input.MsContent);
                } else if (input.getMsg().getMessageTypes().get(i).getMsgType().equals("钉钉消息")) {
                    SendResult = dingDingMsg.Send(toUserCode, input.getMsg().getTitle(), input.getMsg().getMsContent(), input.getMsg().getMobileUrl(), "", input.getMsg().getFromAppCode());
                    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                    DingResponseJson jsonResult = objectMapper.readValue(SendResult, DingResponseJson.class);
                    if (jsonResult.getErrcode() == 0) {
                        msgModel.setSendResultState("成功");
                    } else {
                        msgModel.setSendResultState("失败");
                    }
                } else {
                    //output.setMsgResult(input.getMsg().getMessageType()[i] + "--暂不支持此类型");
                    //throw new ErrorJsonResult("1000013", input.getMsg().getMessageType()[i] + "--暂不支持此类型");
                }

                ObjectUnit.Copy(input.getMsg(),msgModel);
                String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
                msgModel.setId(uuid);
                msgModel.setIsSend(true);
                msgModel.setCreateTime(new Date());
                msgModel.setToNames(toNames);
                msgModel.setSendResult(SendResult);
                msgModel.setMessageType(input.getMsg().getMessageTypes().get(i).getMsgType());
                msgMapper.insertSelective(msgModel);

                for (SendMessageTargetInput item : input.getMsg().getSendMessageTargets()) {
                    MessageTargets messageTarget = new MessageTargets();
                    ObjectUnit.Copy(item,messageTarget);
                    String targetUUid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
                    messageTarget.setId(targetUUid);
                    messageTarget.setMessageId(uuid);
                    messageTarget.setCreateTime(new Date());
                    messageTarget.setIsRead(false);
                    messageTarget.setIsSend(true);
                    messageTarget.setSendTime(new Date());
                    msgTargetMapper.insertSelective(messageTarget);
                }
                msgModels.add(msgModel);
            }
        }else{
            output.setMsgResult("消息类型未找到");
            throw new ErrorJsonResult("1000013","消息类型未找到");
        }
        output.setItem(msgModels);
        output.setMsgResult("发送成功");
        return output;
    }

    /**
     *  创建人:Coke
     *  备注: 补发消息服务
     *  时间: 2019/4/26 14:49 
     *  参数: 
     */
    public ReplenishOutput Replenish(ReplenishInput input) throws Exception {
        ReplenishOutput output = new ReplenishOutput();
        Messages oldMsg = msgMapper.selectByPrimaryKey(input.getMsgId());
        if (oldMsg.getSendResultState().equals("成功")) {
            throw new ErrorJsonResult("100000", "该消息已发送成功,请不要重复发送");
        }
        if (oldMsg.getMessageType().equals("钉钉消息")) {
            String SendResult = "";
            Example example=new Example(MessageTargets.class);
            Example.Criteria criteriaMessageTargets = example.createCriteria();
            criteriaMessageTargets.andEqualTo("messageId", input.getMsgId());
            List<MessageTargets> msgTags = msgTargetMapper.selectByExample(example);
            String toUserCode = "";
            for (MessageTargets item : msgTags) {
                toUserCode += item.getTargetUserCode() + ',';
            }
            if(msgTags.size()>1){
                toUserCode = toUserCode.substring(0, toUserCode.length() - 1);
            }
            SendResult = dingDingMsg.Send(toUserCode, oldMsg.getTitle(), oldMsg.getMsContent(), oldMsg.getMobileUrl(), "", oldMsg.getFromAppCode());
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            DingResponseJson jsonResult = objectMapper.readValue(SendResult, DingResponseJson.class);
            if (jsonResult.getErrcode() == 0) {
                oldMsg.setSendResultState("成功");
            } else {
                oldMsg.setSendResultState("失败");
            }
            oldMsg.setSendResult(SendResult);
        }
        msgMapper.updateByPrimaryKey(oldMsg);
        output.setItem(oldMsg);
        BusinessLogger.Info(LoggerGenre.Update, "补发消息", input);
        return output;
    }

    /**
     *  创建人:Coke
     *  备注: 读取消息
     *  时间: 2019/4/26 14:50 
     *  参数: 
     */
    public ReadMsgOutput ReadMessage(ReadMsgInput input) {

        ReadMsgOutput output = new ReadMsgOutput();
        MessageTargets curMessageTarget = msgTargetMapper.selectByPrimaryKey(input.getMessageTargetId());
        if (curMessageTarget == null) {
            throw new ErrorJsonResult("1000014", "未找到消息信息");
        }
        if (!curMessageTarget.getTargetUserCode().toUpperCase().equals(input.getUserId().toUpperCase())) {
            throw new ErrorJsonResult("1000015", "用户信息错误,请联系管理员");
        }
        if (curMessageTarget.getIsRead()) {
            throw new ErrorJsonResult("1000016", "用户已读");
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        curMessageTarget.setIsRead(true);
        curMessageTarget.setReadTime(new Date());
        msgTargetMapper.updateByPrimaryKey(curMessageTarget);
        output.setResult(true);
        output.setResultMsg("成功");
        return output;
    }

    /**
     *  创建人:Coke
     *  备注: 读取未读消息条数
     *  时间: 2019/4/26 14:50 
     *  参数: 
     */
    public GetUnreadMessageCountOutput GetUnreadMessageCount(GetUnreadMessageCountInput input) {
        GetUnreadMessageCountOutput output = new GetUnreadMessageCountOutput();
        List<MessageTargets> list = msgTargetMapper.getUnreadMessageCount(input);
        output.setCount(list.size());
        return output;
    }

    /**
     *  创建人:Coke
     *  备注: 搜索未读消息
     *  时间: 2019/4/26 14:50 
     *  参数: 
     */
    public SearchMessageListOutput SearchMessageList(SearchMessageListInput input) {
        SearchMessageListOutput output = new SearchMessageListOutput();
        PageHelper.startPage(input.getPage().getPageNo(), input.getPage().getPageSize(), "createTime desc");
        List<MessageTargets> ls = msgTargetMapper.GetAllMessageTargets(input);
        PageInfo<MessageTargets> page = new PageInfo<>(ls);
        output.setItems(new PagedResult<MessageTargets>(page.getList(), (int) page.getTotal()));
        return output;
    }

    /**
     *  创建人:Coke
     *  备注: 加载消息
     *  时间: 2019/4/26 14:50 
     *  参数: 
     */
    public LoadMessageListPageOutput LoadMessageListPage(LoadMessageListPageInput input) {
        LoadMessageListPageOutput output = new LoadMessageListPageOutput();
        DicDto dicDto1 = new DicDto();
        dicDto1.setDicKey("已读");
        dicDto1.setDicCode("true");
        dicDto1.setDicName("已读");
        dicDto1.setDescription("已读");
        DicDto dicDto2 = new DicDto();
        dicDto2.setDicKey("未读");
        dicDto2.setDicCode("false");
        dicDto2.setDicName("未读");
        dicDto2.setDescription("未读");
        List<DicDto> Childrens = new ArrayList<DicDto>();
        Childrens.add(dicDto1);
        Childrens.add(dicDto2);
        DicDto dicPar = new DicDto();
        dicPar.setDicKey("消息状态");
        dicPar.setDicCode("消息状态");
        dicPar.setDicName("消息状态");
        dicPar.setDescription("消息状态");
        dicPar.setChildren(Childrens);
        List<DicDto> curDics = new ArrayList<DicDto>();
        curDics.add(dicPar);
        output.setDics(curDics);
        output.setItems(SearchMessageList(input).getItems());
        return output;
    }

    /**
     *  创建人:Coke
     *  备注: 加载消息
     *  时间: 2019/4/26 14:50 
     *  参数: 
     */
    public LoadManageMessageListPageOutput LoadManageMessageListPage(LoadManageMessageListPageInput input) throws IOException {
        LoadManageMessageListPageOutput output = new LoadManageMessageListPageOutput();
        output.setItems(SearchManageMessageList(input).getItems());
        String GetAppsUrl = remoteProperties.getAppCenterServiceUrl() + "/app/getapps";
        String responseJson = httpAPIService.JsonSMS(GetAppsUrl, "{}");
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        JsonResult jsonResult = objectMapper.readValue(responseJson, JsonResult.class);

        List<Apps> apps = new ArrayList<Apps>();
        Object OneItems = JsonUnit(jsonResult.getResult(), "items");
        ArrayList<Object> TwoItems = (ArrayList<Object>) JsonUnit(OneItems, "items");
        if (TwoItems != null && TwoItems.size() > 0) {
            for (int i = 0; i < TwoItems.size(); i++) {
                Apps app = new Apps();
                app.setId(JsonUnit(TwoItems.get(i), "id").toString());
                app.setAppCode(JsonUnit(TwoItems.get(i), "appCode").toString());
                app.setAppName(JsonUnit(TwoItems.get(i), "appName").toString());
                apps.add(app);
            }
        }
        output.setApps(apps);

        List<ExpandDic> list = new ArrayList<ExpandDic>();
        ExpandDic curExpandDic = new ExpandDic();
        curExpandDic.setId("站内信");
        curExpandDic.setCode("站内信");
        curExpandDic.setText("站内信");
        list.add(curExpandDic);
        curExpandDic = new ExpandDic();
        curExpandDic.setId("钉钉消息");
        curExpandDic.setCode("钉钉消息");
        curExpandDic.setText("钉钉消息");
        list.add(curExpandDic);

        curExpandDic = new ExpandDic();
        curExpandDic.setId("电子邮件");
        curExpandDic.setCode("电子邮件");
        curExpandDic.setText("电子邮件");
        list.add(curExpandDic);
        output.setExpandDics(list);
        return output;
    }

    /**
     *  创建人:Coke
     *  备注: 搜索消息
     *  时间: 2019/4/26 14:51 
     *  参数: 
     */
    public SearchManageMessageListOutput SearchManageMessageList(SearchManageMessageListInput input) throws IOException {
        SearchManageMessageListOutput output = new SearchManageMessageListOutput();
        List<String> UserIds = new ArrayList<String>();
        if(!isBlank(input.getKeyword())){
            String GetUsersUrl = remoteProperties.getAppCenterServiceUrl() + "/user/SearchUsers";
            PagedResultRequest pageUsers = new PagedResultRequest();
            pageUsers.setPageNo(0);
            pageUsers.setPageSize(2047483647);
            pageUsers.setMaxResultCount(2047483647);
            SearchUsersInput userInput = new SearchUsersInput();
            userInput.setKeyword(input.getKeyword());
            userInput.setPage(pageUsers);
            String postGetUserJson = objectMapper.writeValueAsString(userInput);
            String responseJson = httpAPIService.JsonSMS(GetUsersUrl, postGetUserJson);

            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            JsonResult jsonResult = objectMapper.readValue(responseJson, JsonResult.class);

            Object OneItems = JsonUnit(jsonResult.getResult(), "items");
            ArrayList<Object> TwoItems = (ArrayList<Object>) JsonUnit(OneItems, "items");
            if (TwoItems != null && TwoItems.size() > 0) {
                for (int i = 0; i < TwoItems.size(); i++) {
                    UserIds.add(JsonUnit(TwoItems.get(i), "id").toString());
                }
            }
        }
        Example exampleMessageTargets = new Example(MessageTargets.class);
        Example.Criteria criteriaMessageTargets = exampleMessageTargets.createCriteria();
        if(UserIds.size()>0){
            criteriaMessageTargets.andIn("targetUserCode", UserIds);
        }
        List<MessageTargets> msgTags = msgTargetMapper.selectByExample(exampleMessageTargets);
        List<String> msgIds = new ArrayList<String>();
        if (msgTags != null && msgTags.size() > 0) {
            for (int i = 0; i < msgTags.size(); i++) {
                msgIds.add(msgTags.get(i).getMessageId());
            }
        }
        Example exampleMsg = new Example(Messages.class);
        Example.Criteria criteriaMsg = exampleMsg.createCriteria();
        //关键字部分
        if (!isBlank(input.getKeyword())) {
            criteriaMsg.orLike("title", input.getKeyword());
            criteriaMsg.orLike("msContent", input.getKeyword());
            criteriaMsg.orLike("createUserCode", input.getKeyword());
            criteriaMsg.orLike("createUserName", input.getKeyword());

            if (msgIds != null && msgIds.size() > 0) {
                criteriaMsg.orIn("id", msgIds);
            }
        }
        Example.Criteria criteria = exampleMsg.createCriteria();
        if (!isBlank(input.getBusinessType())) {
            criteria.andEqualTo("businessType", input.getBusinessType());
        }
        if (!isBlank(input.getAppCode())) {
            criteria.andEqualTo("toAppCode", input.getAppCode());
        }

        if (!isBlank(input.getMsgType())) {
            criteria.andEqualTo("messageType", input.getMsgType());
        }
        exampleMsg.and(criteria);
        PageHelper.startPage(input.getPage().getPageNo(), input.getPage().getPageSize(), "createTime desc");
        List<Messages> msgs = msgMapper.selectByExample(exampleMsg);
        PageInfo<Messages> page = new PageInfo<>(msgs);
        output.setItems(new PagedResult<Messages>(page.getList(), (int) page.getTotal()));
        return output;
    }

    public Object JsonUnit(Object a, String Key) {
        Map map = (Map) a;
        Iterator iter = map.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            if (entry.getKey().toString().equals(Key)) {
                return entry.getValue();
            }
        }
        return null;
    }

    //以下类为URL获取信息所用类
    class SearchUsersInput extends GetItemsInput {

    }
}
